<script lang="ts" setup>
import { onUnmounted, toRefs, ref, watch } from 'vue'
type itemType = {
  id: number;
  src: string;
}
const props = defineProps({
  list: {
    type: Array,
    default: () => []
  },
  autoplay: {
    type: Boolean,
    default: true
  },
  showDot: {
    type: Boolean,
    default: true
  },
  duration: {
    type: Number,
    default: 3
  },
})

const { list, autoplay, showDot, duration } = toRefs(props)

const index = ref(0)
// 定义⼀个常量存储定时器
const timer = ref(0)
// 定时器⽅法，实现⾃动轮播效果
const autoplayFn = () => {
  // 防抖，防⽌多次触发定时器
  clearInterval(timer.value)
  timer.value = window.setInterval(() => {
    index.value += 1
    if (index.value >= list.value.length) {
      index.value = 0
    }
  }, duration.value * 1000)
}
// 侦听器，根据接⼝返回的数据与传递的相关属性参数 autoplay 开启轮播
// 监听返回的数据的长度，当长度⼤于1的时候并且 autoplay 的为 true 的时候开启轮播
watch(
  list,
  () => {
    if (list.value.length > 1 && autoplay.value) {
      autoplayFn()
    }
  }
)
// ⿏标移⼊轮播图，停⽌⾃动播放
const stop = () => {
  if (timer.value) window.clearInterval(timer.value)
}
// ⿏标移出轮播图，开启定时器
const start = () => {
  if (list.value.length > 1 && autoplay.value) {
    autoplayFn()
  }
}
// 点击轮播图上的左右按钮，切换轮播图，通过传递进来的参数，决定轮播图往左往右
const clickFn = (e: number) => {
  index.value += e
  if (index.value >= list.value.length) {
    index.value = 0
  }
  if (index.value < 0) {
    index.value = list.value.length - 1
  }
}
// 点击指⽰器（轮播图底下的⼩点）切换轮播图
const active = (e: number) => {
  index.value = e
}
// 组件销毁的时候情书定时器，避免性能损耗
onUnmounted(() => {
  if (timer.value) window.clearInterval(timer.value)
})
</script>
<template>
  <div class="carousel-wrapper" @mouseenter="stop" @mouseleave="start">
    <ul class="carousel-body">
      <li v-for="(item, i) in list" :key="i" class="carousel-item" :class="{ fade: index === i }">
        <slot :name="i"></slot>
      </li>
    </ul>
    <div @click="clickFn(-1)" class="carousel-btn prev"></div>
    <div @click="clickFn(1)" class="carousel-btn next"></div>
    <div class="carousel-indicator" v-if="showDot">
      <span @click="active(i)" v-for="(item, i) in list" :key="i" :class="{ active: index === i }"></span>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.carousel-wrapper {
  width: 100%;
  height: 100%;
  min-width: 300px;
  min-height: 150px;
  background-color: #f5f5f5;
  position: relative;

  .carousel {
    &-body {
      width: 100%;
      height: 100%;
    }

    &-item {
      width: 100%;
      height: 100%;
      position: absolute;
      left: 0;
      top: 0;
      opacity: 0;
      transition: opacity 0.5s linear;

      &.fade {
        opacity: 1;
        z-index: 1;
      }

      img {
        width: 100%;
        height: 100%;
      }
    }

    &-indicator {
      position: absolute;
      left: 0;
      bottom: 20px;
      z-index: 2;
      width: 100%;
      text-align: center;

      span {
        display: inline-block;
        width: 12px;
        height: 6px;
        background: rgba(0, 0, 0, 0.2);
        cursor: pointer;

        ~span {
          margin-left: 12px;
        }

        &.active {
          background: #fff;
        }
      }
    }

    &-btn {
      width: 44px;
      height: 44px;
      background: rgba(255, 255, 255, 0.6);
      position: absolute;
      top: 228px;
      z-index: 2;
      text-align: center;
      opacity: 0;
      transition: all 0.5s;
      cursor: pointer;

      &::after {
        content: '';
        position: absolute;
        left: 50%;
        top: 50%;
        width: 8px;
        height: 8px;
        border: solid 1px #626675;
        transform: translate(-50%, -50%) rotate(45deg);
      }

      &.prev {
        left: 20px;

        &::after {
          border-width: 0 0 1px 1px;
        }
      }

      &.next {
        right: 20px;

        &::after {
          border-width: 1px 1px 0 0;
        }
      }
    }
  }

  &:hover {
    .carousel-btn {
      opacity: 1;
    }
  }

  .carousel-btn {
    &:hover {
      background: rgba(255, 255, 255, 0.9);
    }
  }
}
</style>